#include "mp3.h"
#include "media_timer_v2.h"
#include "audio_card.h"
#include "audio_decode.h"
#include "my_malloc.h"
#include "libc.h"
#include "drawtxt.h"
#include "key.h"
#include "mainmenue.h"
void delay_ms(uint32_t wMs);
static audio_player_obj_t *audio_player_obj = NULL;
void audio_player_cycle(void);
extern char task_mark;
#define MUSIC_PATH_FOLDER_ROOT "1:/music"
#define MUSIC_PATH_FOLDER_ONLY "/music/"
#define MUSIC_PATH_NEWFILE_TXT "/music/newfile.txt"

typedef struct mp3_t{
    char path[30];
    uint16_t  dir_offect;
    char mp3_key;
    uint8_t slect_num;
    uint8_t slect_num_totle;
}mp3_t;
mp3_t my_mp3;

void mp3_init(){
    my_mp3.mp3_key = 0;
    my_mp3.dir_offect = 0;
    my_mp3.slect_num = 0;
    my_mp3.slect_num_totle = 4;
}

void show_music_dir(int num){
    FIL file;  // 文件对象
    FRESULT res;  // FatFs返回结果
    char out_buff[128];
    uint32_t rd_len;
    
    res = f_open(&file,  MUSIC_PATH_NEWFILE_TXT, FA_READ);
    if (res == FR_OK) {
        for(int i = 0; i < 4;i++){
            res = f_lseek(&file, (num+i)*128);
            if(res == FR_OK){
                res = f_read(&file, out_buff, 128, &rd_len);
                draw_string(16,16*i ,16,out_buff);
            }
        }
    }
    f_close(&file) ;
}
void slect_file(){
    for(char i =0; i < my_mp3.slect_num_totle; i++){
        draw_char_EN(0,16*i ,16,' ');
    }
    draw_char_EN(0,16*my_mp3.slect_num ,16,'>');
    if(my_mp3.mp3_key == 1){
        my_mp3.mp3_key = 0;
        my_mp3.slect_num++;
    }
}

void mp3_sang(){
    FIL file;  // 文件对象
    FRESULT res;  // FatFs返回结果
    char out_buff[128];
    uint32_t rd_len;
    char str[10];
    char mp3_path[256];
    res = f_open(&file,  MUSIC_PATH_NEWFILE_TXT, FA_READ);
    if (res == FR_OK) {
        res = f_lseek(&file, (my_mp3.dir_offect + my_mp3.slect_num)*128); 
        if(res == FR_OK){
            res = f_read(&file, out_buff, 128, &rd_len);
            //draw_string(16,16*i ,16,out_buff);
            strcpy(mp3_path,MUSIC_PATH_FOLDER_ONLY);
            strcpy(&mp3_path[strlen(mp3_path)],out_buff);
        }
        f_close(&file) ;
    }
    OLED_Clear();
    draw_string(0,16*0 ,16,out_buff);
    audio_player_start2(mp3_path);
    //audio_player_obj->sample_freq;
    str[0] = audio_player_obj->sample_freq / 1000000%10 +'0';
    str[1] = audio_player_obj->sample_freq / 100000%10 +'0';
    str[2] = audio_player_obj->sample_freq / 10000%10 +'0';
    str[3] = audio_player_obj->sample_freq / 1000%10 +'0';
    str[4] = audio_player_obj->sample_freq / 100%10 +'0';
    str[5] = audio_player_obj->sample_freq / 10%10 +'0';
    str[6] = audio_player_obj->sample_freq / 1%10 +'0';
    str[7] = 0;
    draw_string(0,16*1 ,16,str);
    
    str[0] = audio_player_obj->sample_bits /10 %10 +'0';
    str[1] = audio_player_obj->sample_bits /1 %10 +'0';
    str[2] = 0;
    draw_string_fast_EN(64,16*1 ,16,str);
    
}
void show_play_time(){
    static int time = 0;
    int played_time,total_time;
    int fen,miao; 
    char data[20];
    if(time >= 50){
        played_time = audio_file_get_played_time();
        total_time  = audio_file_get_total_time();
        fen = total_time / 60;
        miao =  total_time % 60;
        data[0] = fen / 100 % 10 + '0';
        data[1] = fen / 10 % 10 + '0';
        data[2] = fen / 1 % 10 + '0';
        data[3] = ':';
        data[4] = miao / 10 % 10 + '0';
        data[5] = miao / 1 % 10 + '0';
        data[6] = '-';
        data[7] = '-';
        fen = played_time / 60;
        miao =  played_time % 60;
        data[8] = fen / 100 % 10 + '0';
        data[9] = fen / 10 % 10 + '0';
        data[10] = fen / 1 % 10 + '0';
        data[11] = ':';
        data[12] = miao / 10 % 10 + '0';
        data[13] = miao / 1 % 10 + '0';
        data[14] = 0;
        draw_string_fast_EN(0,16*2 ,16,data);
        time = 0;
    }else{
        time++;
    }
   
    
}
void mp3_sanging(char *flag){
    int ret;
    
        if((task_mark == 0x01))
        {
            task_mark = 0;
            
            if(audio_player_obj->state == AUDIO_PLAYER_PLAYING)
            {
                ret = audio_file_decode_stream(audio_player_obj->pcm_buff, PCM_BUFF_SIZE);
                if(ret > 0)
                {
                    audio_card_write(audio_player_obj->pcm_buff, ret);
                    ret++;
                    
                    show_play_time();

                    //显示声音的时域波形(每2包音频数据显示一包即可; 如果追求实时性, 可以每包数据都显示波形)
//                    if( is_show_wave ) 
//                    {
//                        audio_player_obj->count++;
//                        if((audio_player_obj->count & 0x01) == 0)
//                            audio_player_show_sound_wave();
//                    }
                }
                else
                {	//解码异常或者音频文件解码完成

                    task_mark = 0;           //使下面的if((task_mark & 0x02))不再执行
                    audio_player_stop();
                    *flag=1;
                    return;
                    //goto sang;
                    
                }
            }
            else
            {
                u_memset(audio_player_obj->pcm_buff, 0x00, audio_player_obj->pcm_pkg_size);
                audio_card_write(audio_player_obj->pcm_buff, audio_player_obj->pcm_pkg_size);
    //			my_printf("Audio player pause, Feed 0x00 to sound card!\n\r");
            }
        }
        *flag=0;

}
void mp3_task(){
    static char state = 0;
    char flag = 0;
    switch(state){
        case 0:            
            mp3_init();
            state = 1;
        break;
        case 1://显示目录
            OLED_Clear(); 
            show_music_dir(my_mp3.dir_offect);
            state = 2;
        break;
        case 2://选择文件
            slect_file();
            if(my_mp3.slect_num >= my_mp3.slect_num_totle){
                my_mp3.slect_num = 0;
                my_mp3.dir_offect += my_mp3.slect_num_totle;
                state = 1;
            }
            if(my_mp3.mp3_key == 2){
                my_mp3.mp3_key = 0;
                state = 3;
            }
        break;
        case 3://播放歌曲mp3
            mp3_sang();
            state = 4;
        break;
        case 4:
            
            while(1){
                mp3_sanging(&flag);
                if(flag){
                    state = 3;
                    break;
                }
                my_mp3.mp3_key = key_scan();
                if(my_mp3.mp3_key == 2){
                    task_mark = 0;           //使下面的if((task_mark & 0x02))不再执行
                    audio_player_stop();
                    state = 0;
                    break;
                }
            }
            //my_mp3.mp3_key = 0;
            
        break;
    }

}

void test_audio(void){
    //find_mp3();
    char key_num = 0;
    while(1){
        
        key_num = key_scan();
        if(key_num){
            my_mp3.mp3_key = key_num;
        }
        mp3_task();
        if(my_mp3.mp3_key == 2){
            my_mp3.mp3_key = 0;
            main_exit();
            break;
        }
        delay_ms(10);
    }
}

void find_mp3(){
    FRESULT res;  // FatFs返回结果
    DIR dir;      // 目录对象
    FILINFO fno;  // 文件信息结构体
    
    int i = 0;
    // 尝试打开目录
    res = f_opendir(&dir,  MUSIC_PATH_FOLDER_ROOT);
    if (res != FR_OK) {
        //printf("打开目录失败，错误码：%d\n", res);
        return;
    }
    // 循环读取目录项
    while (1) {
        res = f_readdir(&dir, &fno);  // 读取一个目录项
        if (res != FR_OK || fno.fname[0] == 0) break;  // 出错或到达目录尾部时退出循环
        if (fno.fattrib & AM_DIR) {
            // 这是一个目录
            //draw_string(0,0,16,fno.fname);
        }else{
            // 这是一个文件，尝试打开
//            if(i == 0){
//                strcpy(my_mp3.path,"/music/");
//                strcpy(&my_mp3.path[7],fno.fname);
//            }
            FIL file;  // 文件对象
            UINT bw;
           // 以写入模式打开文件，如果不存在则创建
            if (f_open(&file, MUSIC_PATH_NEWFILE_TXT, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK) {
                //error("File open failed");
                return;
            }
            res = f_lseek(&file, i*128);
            
            if (res == FR_OK) {
                //const char *data = "追加的数据\n";
                res = f_write(&file, fno.fname, 128, &bw); // 写入数据
                f_sync(&file); // 刷新数据
            }
            
            // 关闭文件
            if (f_close(&file) != FR_OK) {
                //error("File close failed");
                return;
            }
            
            //strcpy(&temp_buff[i][0],fno.fname);
            i++;
        }

    }
    f_closedir(&dir);  // 关闭目录
    draw_string(16,16*1 ,16,"find ok");

}

//Timer定时周期 1000ms
static void audio_timer_isr(void)
{
	//tcb_audio_player.mark |= 0x02;
	//task_wakeup(&tcb_audio_player);
    audio_player_cycle();

}
static void audio_timer_start(void)
{
	//启动一个1000ms的定时器
	//10KHz即100us, 100us*10000=1000ms=1s
	media_timer_start(10000, 10000, audio_timer_isr);
}

static void audio_timer_stop(void)
{
	media_timer_stop();
}




/** @brief 关闭音频播放器
 */
void audio_player_stop(void)
{
	audio_timer_stop();
	//task_delete(&tcb_audio_player);    //删除audio任务

	if(audio_player_obj != NULL)
	{
		audio_card_close();    //关闭声卡

		audio_file_close();

		mem_free(audio_player_obj->pcm_buff);
		mem_free(audio_player_obj);
		audio_player_obj = NULL;
	}	
}




//只需激活音频解码任务
static void audio_player_feeding_sound_card(void)
{
	//tcb_audio_player.mark |= 0x01;
	//task_wakeup(&tcb_audio_player);
    task_mark = 1;
}

#include "fs_app.h"
//===============================================================================================================

void show_mp3(){
    FRESULT res;  // FatFs返回结果
    DIR dir;      // 目录对象
    FILINFO fno;  // 文件信息结构体
    
    int i = 0;
    // 尝试打开目录
    res = f_opendir(&dir,  "1:/music");
    if (res != FR_OK) {
        //printf("打开目录失败，错误码：%d\n", res);
        return;
    }
    // 循环读取目录项
    while (1) {
        res = f_readdir(&dir, &fno);  // 读取一个目录项
        if (res != FR_OK || fno.fname[0] == 0) break;  // 出错或到达目录尾部时退出循环
        if (fno.fattrib & AM_DIR) {
            // 这是一个目录
            //draw_string(0,0,16,fno.fname);
        }else{
            // 这是一个文件，尝试打开
            if(i == 0){
                strcpy(my_mp3.path,"/music/");
                strcpy(&my_mp3.path[7],fno.fname);
            }
            if(i<4)
            draw_string(16,16*i ,16,fno.fname);
            i++;
            //strcpy(&temp_buff[i][0],fno.fname);
            //i++;
        }

    }
    f_closedir(&dir);  // 关闭目录

}

char task_mark = 0;


void test_audio44(){
    show_mp3();
    int ret;
    //draw_string(0,16*2 ,16,my_mp3.path);
    
sang:    
    audio_player_start2("/music/01.mp3");
    
    while(1){
        if((task_mark == 0x01))
        {
            task_mark = 0;
            if(audio_player_obj->state == AUDIO_PLAYER_PLAYING)
            {
                ret = audio_file_decode_stream(audio_player_obj->pcm_buff, PCM_BUFF_SIZE);
                if(ret > 0)
                {
                    audio_card_write(audio_player_obj->pcm_buff, ret);
                    ret++;

                    //显示声音的时域波形(每2包音频数据显示一包即可; 如果追求实时性, 可以每包数据都显示波形)
//                    if( is_show_wave ) 
//                    {
//                        audio_player_obj->count++;
//                        if((audio_player_obj->count & 0x01) == 0)
//                            audio_player_show_sound_wave();
//                    }
                }
                else
                {	//解码异常或者音频文件解码完成

                    task_mark = 0;           //使下面的if((task_mark & 0x02))不再执行
                    audio_player_stop();
                    goto sang;
                    
                }
            }
            else
            {
                u_memset(audio_player_obj->pcm_buff, 0x00, audio_player_obj->pcm_pkg_size);
                audio_card_write(audio_player_obj->pcm_buff, audio_player_obj->pcm_pkg_size);
    //			my_printf("Audio player pause, Feed 0x00 to sound card!\n\r");
            }
        }
    }
}

int  audio_player_start2(char *fname){
    int ret;
    if(audio_player_obj != NULL)
	{
		audio_player_stop();
	}

	audio_player_obj = mem_malloc(sizeof(audio_player_obj_t));
    if(audio_player_obj == NULL)
	{
		return -1;
	}
    audio_player_obj->pcm_buff =  mem_malloc(PCM_BUFF_SIZE);
	if(audio_player_obj->pcm_buff == NULL)
	{
		mem_free(audio_player_obj);
		audio_player_obj = NULL;
		return -2;
	}
    
    ret = audio_file_open(fname);
    if(ret != 0)
	{
		mem_free(audio_player_obj->pcm_buff);
		mem_free(audio_player_obj);
		audio_player_obj = NULL;
		return -3;
	}
    
    ret = audio_file_get_attr_info(&audio_player_obj->sample_freq, &audio_player_obj->channels, &audio_player_obj->sample_bits);
    if(ret != 0)
	{
		audio_file_close();
		mem_free(audio_player_obj->pcm_buff);
		mem_free(audio_player_obj);
		audio_player_obj = NULL;
		return -4;
	}

	//获取一包音频数据
	ret = audio_file_decode_stream(audio_player_obj->pcm_buff, PCM_BUFF_SIZE);
    
    if(ret <= 0)
	{
		audio_file_close();
		mem_free(audio_player_obj->pcm_buff);
		mem_free(audio_player_obj);
		audio_player_obj = NULL;
		return -5;		
	}
	audio_player_obj->pcm_pkg_size = ret;
    
    //打开声卡
	ret = audio_card_open(audio_player_obj->sample_freq, audio_player_obj->channels, audio_player_obj->sample_bits, audio_player_obj->pcm_buff, audio_player_obj->pcm_pkg_size);
	if(ret != 0)
	{
		audio_file_close();
		mem_free(audio_player_obj->pcm_buff);
		mem_free(audio_player_obj);
		audio_player_obj = NULL;
		return -6;
	}	
    
    //注册回调函数,并检查声卡音量
	audio_card_register_feeder(audio_player_feeding_sound_card);
    
    audio_player_obj->state = AUDIO_PLAYER_PLAYING;

    
    return 0;
}

